#ifndef THREADS_H
#define THREADS_H

#include <limits>
#include <mutex>
#include <list>
#include <atomic>
#include <condition_variable>
#include "util.h"

template<typename T>
class SafeQueue : private std::mutex, private noncopyable {
    static const int wait_infinite = std::numeric_limits<int>::max();
public:
    SafeQueue(size_t capacity = 0) : capacity_(capacity), exit_(false) {}
    bool push(T &&v);
    T pop_wait(int waitMs = wait_infinite);

    size_t size();
    void exit();
    bool exited() { return exit_; }

private:
    void wait_ready(std::unique_lock<std::mutex>& lk, int wait_ms);

private:
    std::list<T> items_;
    std::condition_variable ready_;
    size_t capacity_;
    std::atomic<bool> exit_;
};

#endif // THREADS_H
